/*
 * Copyright (c) 2009, Jan Pastor. All Rights Reserved.
 */

package sk.jp.commons.utils.xml;

import java.io.IOException;
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 * XML builder wrapper. Use this class to generate XML documents.
 */
public class XmlBuilderTools {

    /**
     * Singleton instance of this class.
     */
    private static XmlBuilderTools instance = null;

    private DocumentBuilder builder = null;

    //----------------------------------------------------------------------

    /**
     * Initaialize builder.
     *
     * @throws XmlException
     */
    public XmlBuilderTools() throws XmlException {
        try {
            this.builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        } catch (FactoryConfigurationError e) {
            throw new XmlException("Error in XML builder factory configuration: " + e.getMessage(), e);
        } catch (ParserConfigurationException e) {
            throw new XmlException("Error in XML parser configuration: " + e.getMessage(), e);
        }
    }

    /**
     * Get <code>XmlBuilderTools</code> instance.
     *
     * @return XmlBuilderTools instance
     * @throws XmlException
     */
    public static synchronized XmlBuilderTools getInstance() throws XmlException {
        if (instance == null){
            instance = new XmlBuilderTools();
        }
        return instance;
    }

    //----------------------------------------------------------------------

    /**
     * Parse <code>Document</code> from <code>InputStream</code>
     *
     * @param is InputStream of document to create
     * @return DOM of document
     * @throws XmlException
     */
    public Document parseDocument(InputStream is) throws XmlException {
        try {
            return builder.parse(is);
        } catch (IOException e) {
            throw new XmlException("Parsing IO error: " + e.getMessage(), e);
        } catch (SAXException e) {
            throw new XmlException("Parsing SAX error: " + e.getMessage(), e);
        }
    }

    /**
     * Parse <code>Document</code> from <code>InputSource</code>
     *
     * @param s InputStream of document to create
     * @return DOM of document
     * @throws XmlException
     */
    public Document parseDocument(InputSource s) throws XmlException {
        try {
            return builder.parse(s);
        } catch (IOException e) {
            throw new XmlException("Parsing IO error: " + e.getMessage(), e);
        } catch (SAXException e) {
            throw new XmlException("Parsing SAX error: " + e.getMessage(), e);
        }
    }


    /**
     * Create new <code>Document</code>
     *
     * @return document
     */
    public Document createDocument() {
        return builder.newDocument();
    }
}